﻿#ifndef WRDATAPACKET_H
#define WRDATAPACKET_H

#include "../WRGlobal.h"

//表示数据包。
class WRDataPacket
{
private:
    //引用计数。
    QAtomicInt m_refCnt;

    //禁止复制构造函数和赋值操作符。
    Q_DISABLE_COPY(WRDataPacket)

protected:
    //清理当前对象所占用的相关资源。
    virtual ~WRDataPacket()
    {
        //add code here
    }

public:
    //初始化数据包。
    inline WRDataPacket(void)
        : m_refCnt(1)
    {
        //add code here
    }

    //添加对象引用。
    inline void addRef(void)
    {
        m_refCnt.ref();
    }
    //释放对象引用, 如果引用计数为0，则删除对象，返回True，否则返回False。
    inline bool release(void)
    {
        if (!m_refCnt.deref())
        {
            delete this;
            return true;
        }
        return false;
    }

    //获取数据缓存。
    virtual int buffer(char** p) = 0;
    //当完成后调用此方法。
    virtual void fulfil(int length) = 0;

    //创建指定缓存长度的数据包，在释放后将删除缓存。
    static WRDataPacket* create(int length);
    //分配指定缓存长度的数据包，在释放后将删除缓存。
    template <int N> static WRDataPacket* allocate(void);
};

namespace WRPriv
{
    namespace DataPackets
    {
        //表示直接数据包。
        class Direct : public WRDataPacket
        {
        private:
            int m_length;
            char* m_buffer;

            //禁止复制构造函数和赋值操作符。
            Q_DISABLE_COPY(Direct)

            //清理当前对象所占用的相关资源。
            ~Direct(void)
            {
                delete[] m_buffer;
            }

        public:
            //初始化直接数据包。
            explicit Direct(int length)
                : m_length(length), m_buffer(new char[length])
            {
                //add code here
            }

            //获取数据缓存。
            int buffer(char** p)
            {
                *p = m_buffer;
                return m_length;
            }
            //当完成后调用此方法。
            void fulfil(int)
            {
                //add code here
            }
        };
        //表示简单数据包。
        template <int N> class Simple : public WRDataPacket
        {
        private:
            char m_buffer[N];

            //禁止复制构造函数和赋值操作符。
            Q_DISABLE_COPY(Simple)

            //清理当前对象所占用的相关资源。
            ~Simple(void)
            {
                //add code here
            }

        public:
            //初始化简单数据包。
            Simple(void)
            {
                //add code here
            }

            //获取数据缓存。
            int buffer(char** p)
            {
                *p = m_buffer;
                return N;
            }
            //当完成后调用此方法。
            void fulfil(int)
            {
                //add code here
            }
        };
    }
}

//创建指定缓存长度的数据包，在释放后将删除缓存。
inline WRDataPacket* WRDataPacket::create(int length)
{
    return new WRPriv::DataPackets::Direct(length);
}
//分配指定缓存长度的数据包，在释放后将删除缓存。
template <int N> inline WRDataPacket* WRDataPacket::allocate(void)
{
    return new WRPriv::DataPackets::Simple<N>();
}

#endif // WRDATAPACKET_H
